package org.lestr.secuel.sogl.entrees;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Collection;

import org.lestr.secuel.m3ds.entrees.Axe;
import org.lestr.secuel.m3ds.entrees.AxeEcouteur;
import org.lestr.secuel.m3ds.entrees.Bouton;
import org.lestr.secuel.m3ds.entrees.BoutonEcouteur;
import org.lestr.secuel.m3ds.entrees.Entree;
import org.lestr.secuel.sogl.SOGLAffichage;


public class Souris implements Entree {
	
	
	// Déclaration des attributs
	private Collection<Axe> axes;
	private Collection<Bouton> boutons;
	
	
	/** Constructeur */
	public Souris(){
		
		// Instanciation des attributs
		axes = new ArrayList<Axe>();
		boutons = new ArrayList<Bouton>();
		
		// Ajoute les axes X et Y à la liste des axes
		axes.add(new AxeX());
		axes.add(new AxeY());
		
		// Ajoute les boutons de la souris à la liste des boutons
		boutons.add(new BoutonSouris(Bouton.SOURIS_1, MouseEvent.BUTTON1));
		boutons.add(new BoutonSouris(Bouton.SOURIS_2, MouseEvent.BUTTON2));
		boutons.add(new BoutonSouris(Bouton.SOURIS_3, MouseEvent.BUTTON3));
		
	}// FIN Constructeur
	
	
	/** Retourne le nom de l'entrée */
	public String getNom(){
		
		return Entree.SOURIS;
		
	}// FIN retNom

	
	/** Retourne les boutons de l'entrée */
	public Collection<Bouton> getBoutons(){
		
		return boutons;
		
	}// FIN retBoutons
	
	
	/** Retourne les axes de l'entrée */
	public Collection<Axe> getAxes(){
		
		return axes;
		
	}// FIN retAxes
	
	
	/** Bouton de souris */
	private class BoutonSouris implements Bouton {
		
		
		// Déclaration des attributs
		private String nom;
		private int bouton;
		private boolean appuyé;
		private Collection<BoutonEcouteur> écouteurs;
		
		
		/** Constructeur */
		public BoutonSouris(String nom, int leBouton){
		
			// Instanciation des attributs
			this.nom = nom;
			this.bouton = leBouton;
			appuyé = false;
			écouteurs = new ArrayList<BoutonEcouteur>();
			
			// Pose d'écouteurs
			SOGLAffichage.retSingleton().getComponent().addMouseListener(new MouseAdapter(){
				
				@Override
				public void mousePressed(MouseEvent e) {
					
					// Si c'est le bon bouton
					if(e.getButton() == bouton){
					
						// Mémorise le fait que l'on soit appuyé
						appuyé = true;
						
						// Prévient les écouteurs
						for(BoutonEcouteur écouteur : écouteurs)
							écouteur.etatChange(BoutonSouris.this);
						
					}
						
				}
				
				@Override
				public void mouseReleased(MouseEvent e) {
					
					// Si c'est le bon bouton
					if(e.getButton() == bouton){
					
						// Mémorise le fait que l'on soit appuyé
						appuyé = false;
						
						// Prévient les écouteurs
						for(BoutonEcouteur écouteur : écouteurs)
							écouteur.etatChange(BoutonSouris.this);
						
					}
						
				}
				
			});
			
			
		}// FIN Constructeur
		
		
		/** Retourne le nom du bouton */
		public String getNom(){
			
			return nom;
			
		}// FIN 
		
		
		/** Retourne vrai si le bouton est appuyé */
		public boolean isAppuyé(){
			
			return appuyé;
			
		}// FIN 
		
		
		/** Ajoute un écouteur au bouton */
		public void ajoutEcouteur(BoutonEcouteur écouteur){
			
			écouteurs.add(écouteur);
			
		}// FIN 
		
		
		/** Retire un écouteur du bouton */
		public void retraitEcouteur(BoutonEcouteur écouteur){
			
			écouteurs.remove(écouteur);
			
		}// FIN 
		
		
	}// FIN ClasseBoutonSouris
	
	
	/** Axe X de la souris */
	private class AxeX implements Axe {
		
		
		// Déclaration des attributs
		private double ancX;
		private Collection<AxeEcouteur> écouteurs;
		
		
		/** Constructeur */
		public AxeX(){
			
			// Instanciation des attributs
			écouteurs = new ArrayList<AxeEcouteur>();
			ancX = -1;
			
			// Pose d'écouteurs
			SOGLAffichage.retSingleton().getComponent().addMouseMotionListener(new MouseMotionListener(){

				public void mouseDragged(MouseEvent e) {
					
					// Prévient les écouteurs
					for(AxeEcouteur écouteur : écouteurs)
						écouteur.positionChangée(AxeX.this, ancX < 0 ? (double) e.getX() : ancX);
					
					// Mémorise l'ancienne position de x
					ancX = e.getX();
					
				}

				public void mouseMoved(MouseEvent e) {
					
					// Prévient les écouteurs
					for(AxeEcouteur écouteur : écouteurs)
						écouteur.positionChangée(AxeX.this, ancX < 0 ? (double) e.getX() : ancX);
					
					// Mémorise l'ancienne position de x
					ancX = e.getX();
					
				}
				
			});
			
		}// FIN Constructeur
		
		
		/** Retourne le nom de l'axe */
		public String getNom(){
			
			return Axe.SOURIS_X;
			
		}// FIN retNom

		
		/** Retourne la position  minimale de l'axe */
		public double getMinimum(){
			
			return 0;
			
		}// FIN retMinimum

		
		/** Retourne la position  maximale de l'axe */
		public double getMaximum(){
			
			return SOGLAffichage.retSingleton().getComponent().getSize().width;
			
		}// FIN retMaximum

		
		/** Retourne la position du curseur sur l'axe */
		public double getPosition(){
			
			return SOGLAffichage.retSingleton().getComponent().getMousePosition().x;
			
		}// FIN retPosition
		
		
		/** Ajoute un écouteur à l'axe */
		public void ajoutEcouteur(AxeEcouteur écouteur){
			
			écouteurs.add(écouteur);
			
		}// FIN ajoutEcouteur
		
		
		/** Retire un écouteur de l'axe */
		public void retraitEcouteur(AxeEcouteur écouteur){
			
			écouteurs.remove(écouteur);
			
		}// FIN retraitEcouteur
		
		
	}// FIN Classe AxeX
	
	
	/** Axe Y de la souris */
	private class AxeY implements Axe {
		
		
		// Déclaration des attributs
		private double ancY;
		private Collection<AxeEcouteur> écouteurs;
		
		
		/** Constructeur */
		public AxeY(){
			
			// Instanciation des attributs
			écouteurs = new ArrayList<AxeEcouteur>();
			ancY = -1;
			
			// Pose d'écouteurs
			SOGLAffichage.retSingleton().getComponent().addMouseMotionListener(new MouseMotionListener(){

				public void mouseDragged(MouseEvent e) {
					
					// Prévient les écouteurs
					for(AxeEcouteur écouteur : écouteurs)
						écouteur.positionChangée(AxeY.this, ancY < 0 ? (double) e.getX() : ancY);
					
					// Mémorise l'ancienne position de x
					ancY = e.getY();
					
				}

				public void mouseMoved(MouseEvent e) {
					
					// Prévient les écouteurs
					for(AxeEcouteur écouteur : écouteurs)
						écouteur.positionChangée(AxeY.this, ancY < 0 ? (double) e.getX() : ancY);
					
					// Mémorise l'ancienne position de x
					ancY = e.getY();
					
				}
				
			});
			
		}// FIN Constructeur
		
		
		/** Retourne le nom de l'axe */
		public String getNom(){
			
			return Axe.SOURIS_Y;
			
		}// FIN retNom

		
		/** Retourne la position  minimale de l'axe */
		public double getMinimum(){
			
			return 0;
			
		}// FIN retMinimum

		
		/** Retourne la position  maximale de l'axe */
		public double getMaximum(){
			
			return SOGLAffichage.retSingleton().getComponent().getSize().height;
			
		}// FIN retMaximum

		
		/** Retourne la position du curseur sur l'axe */
		public double getPosition(){
			
			return SOGLAffichage.retSingleton().getComponent().getMousePosition().y;
			
		}// FIN retPosition
		
		
		/** Ajoute un écouteur à l'axe */
		public void ajoutEcouteur(AxeEcouteur écouteur){
			
			écouteurs.add(écouteur);
			
		}// FIN ajoutEcouteur
		
		
		/** Retire un écouteur de l'axe */
		public void retraitEcouteur(AxeEcouteur écouteur){
			
			écouteurs.remove(écouteur);
			
		}// FIN retraitEcouteur
		
		
	}// FIN Classe AxeY
	

}// FIN Classe
